﻿using System;
using System.Text;

using Castle.DynamicProxy;
using System.Reflection;
using Janus.Cores.Logger;

namespace Janus.Cores.DynamicProxy.CastleDynamic.Interception
{
    /// <summary>
    /// 功能：表示异常处理的拦截。
    /// 作者：luochengbang@163.com
    /// 日期：2012/2/24 16:58:20 
    /// 备注：本代码版权归Janus所有，严禁外传 
    /// </summary>
    public class ExceptionHandlingInterceptor : HandlingInterceptorBase
    {
        #region 私有方法
        private object GetReturnValueByType(Type type)
        {
            if (type.IsClass || type.IsInterface)
                return null;
            if (type == typeof(void))
                return null;
            return Activator.CreateInstance(type);
        }
        #endregion

        /// <summary>
        /// 执行拦截动作，做统一的异常处理。
        /// </summary>
        /// <param name="invocation"></param>
        public override void DoIntercept(IInvocation invocation)
        {
            try
            {
                invocation.Proceed();
            }
            catch (Exception ex)
            {
                MemberInfo memberInfo = invocation.Method;
                string name = string.Empty;
                name = CreateName(memberInfo);

                //Logger.Monitor(ExceptionSerialize(ex), "Interface", name, ex);
                LogManager.Default.Error(ExceptionSerialize(ex));
                invocation.ReturnValue = GetReturnValueByType(invocation.Method.ReturnType);
                //bool handled = ExceptionManager.HandleException(ex);
                //if (!handled)
                throw;
            }
        }
        /// <summary>
        /// 从异常中序列化成友好异常信息
        /// </summary>
        /// <param name="exception">需要序列化的异常对象</param>
        /// <returns>格式化的异常信息</returns>
        private string ExceptionSerialize(Exception exception)
        {
            if (null == exception) return string.Empty;

            StringBuilder exceptionMsg = new StringBuilder();
            exceptionMsg.AppendLine();
            exceptionMsg.AppendLine(exception.Message);
            exceptionMsg.Append(exception.StackTrace);
            exceptionMsg.AppendLine();
            foreach (var key in exception.Data.Keys)
            {
                exceptionMsg.AppendFormat("{0}:{1}", key, exception.Data[key]);
                exceptionMsg.AppendLine();
            }
            if (exception.InnerException != null)
            {
                exceptionMsg.Append(ExceptionSerialize(exception.InnerException));
            }

            return exceptionMsg.ToString();
        }
    }
}

